﻿package we3d.renderer.realistic 
{
	import we3d.mesh.Vertex;
	import we3d.View3d;
	import we3d.renderer.IRenderer
	import we3d.core.Camera3d;
	import we3d.scene.SceneObject;
	import we3d.mesh.Face;
	import we3d.math.Matrix3d;
	
	/**
	* Object Culling, Backface Culling
	*/
	public class Default implements IRenderer 
	{
		public function Default () {}
		
		public function draw (view:View3d) :void {
			
			var f:Number = view.scene.currentFrame;
			var v:Camera3d = view.scene.cam;
			var objectList:Array = view.scene.objectList;
			var objs:int = objectList.length;
			var cgv:Matrix3d = new Matrix3d();
			
			var gv:Matrix3d;
			var p:Face;
			var o:SceneObject;
			var i:int;
			var j:int;
			var k:int;
			var L:int;
			var pL:int;
			var r:Array;
			var ofc:int;
			var vtxs:Array;
			var vtxa:Vertex;
			var vtxb:Vertex;
			var x:Number;
			var y:Number;
			var z:Number;
			
			var camx:Number = v.transform.gv.m;
			var camy:Number = v.transform.gv.n;
			var camz:Number = v.transform.gv.o;
			
			view.initFrame(f);
			
			var rObjCount:int=0;
			
			for(i=0; i<objs; i++) {
				
				o = objectList[i];
				if(o.initFrame(f, v, cgv)) continue;
				if(o.initMesh(view, cgv)) continue;
				
				rObjCount++;
				
				r = o.polygons;
				L = r.length;
				
				ofc = o.frameCounter;
				gv = o.transform.gv;
				
				for(j=0; j<L; j++) {
					
					p = r[j];
					pL = p.vLen;
					if(pL < 2) continue;
					
					vtxb = p.normal;
					vtxb.wz = gv.c * vtxb.x + gv.g * vtxb.y + gv.k * vtxb.z;
					vtxb.wy = gv.b * vtxb.x + gv.f * vtxb.y + gv.j * vtxb.z;
					vtxb.wx = gv.a * vtxb.x + gv.e * vtxb.y + gv.i * vtxb.z;
					
					if(p.surface.hideBackfaces) {
						vtxa = p.a;
						z = gv.c * vtxa.x + gv.g * vtxa.y + gv.k * vtxa.z + gv.o - camz;
						y = gv.b * vtxa.x + gv.f * vtxa.y + gv.j * vtxa.z + gv.n - camy;
						x = gv.a * vtxa.x + gv.e * vtxa.y + gv.i * vtxa.z + gv.m - camx;
					
						if(x*vtxb.wx + y*vtxb.wy + z*vtxb.wz < 0) continue;
					}
					
					vtxs = p.vtxs;
					
					for(k=0; k<pL; k++) {
						vtxb = vtxs[k];
						if(vtxb.frameCounter1 != ofc) {
							vtxb.wz = cgv.c * vtxb.x + cgv.g * vtxb.y + cgv.k * vtxb.z + cgv.o;
							vtxb.wy = cgv.b * vtxb.x + cgv.f * vtxb.y + cgv.j * vtxb.z + cgv.n;
							vtxb.wx = cgv.a * vtxb.x + cgv.e * vtxb.y + cgv.i * vtxb.z + cgv.m + v._nearClipping;
							if(vtxb.wz > 0) {
								vtxb.sx = v.t + vtxb.wx/vtxb.wz * v.t;
								vtxb.sy = v.s - vtxb.wy/vtxb.wz * v.s;
							}else{
								vtxb.sx = v.t + vtxb.wx* v.t;
								vtxb.sy = v.s - vtxb.wy * v.s;
							}
							vtxb.frameCounter1 = ofc;
						}
					}
					
					o.polyRenderer.drawPoly(view, p);
				}
			}
			
			view.renderInfo.renderedObjects = rObjCount;
			
			view.endFrame(f);
		}
		
	}
}